/*
 * Copyright (C) 2013 SeekDeepWithin.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package com.seekdeepwithin.Controls;

import com.seekdeepwithin.Resources.*;
import java.util.*;
import javafx.animation.*;
import javafx.application.*;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.util.*;

/**
 * User: Jonathan Montiverdi Date: Sep 27, 2013
 *
 *
 */
public class InformationBar extends HBox
{
   public final static int ICON_ERROR = 0;
   public final static int ICON_WARNING = 1;
   public final static int ICON_INFO = 2;
   private final double EXPAND_HEIGHT = 45;
   private final Animation m_ShowInfoBar;
   private final Animation m_HideInfoBar;
   private final ImageView m_ImageView;
   private final Label m_TextLabel;
   private final Button m_CloseButton;
   private final Timer m_Timer;
   private boolean m_IsShown;

   /**
    * Initializes a new information bar.
    */
   public InformationBar ()
   {
      this.setId ("infobar");
      this.setSpacing (5);
      this.setMinHeight (0);
      this.setAlignment (Pos.CENTER_LEFT);
      this.setPrefHeight (0);
      this.setTranslateY (-75);

      this.m_ImageView = new ImageView ();
      HBox.setMargin (this.m_ImageView, new Insets (0, 0, 0, 5));
      this.m_ImageView.setImage (new Image (SdwResources.ICON_INFO));
      this.getChildren ().add (this.m_ImageView);

      this.m_TextLabel = new Label ();
      this.m_TextLabel.setWrapText (true);
      this.m_TextLabel.setId ("infobartext");
      this.getChildren ().add (this.m_TextLabel);

      Region region = new Region ();
      HBox.setHgrow (region, Priority.ALWAYS);
      this.getChildren ().add (region);

      this.m_CloseButton = new Button ();
      this.m_CloseButton.setId ("infobarclose");
      HBox.setMargin (this.m_CloseButton, new Insets (0, 5, 0, 0));
      this.m_CloseButton.setOnAction (new EventHandler<ActionEvent> ()
      {
         @Override
         public void handle (ActionEvent t)
         {
            hide ();
         }
      });
      this.getChildren ().add (this.m_CloseButton);

      this.m_ShowInfoBar = new Transition ()
      {
         {
            setCycleDuration (Duration.millis (250));
         }

         @Override
         protected void interpolate (double d)
         {
            final double curWidth = EXPAND_HEIGHT * d;
            setPrefHeight (curWidth);
            setTranslateY (-EXPAND_HEIGHT + curWidth);
         }
      };

      this.m_HideInfoBar = new Transition ()
      {
         {
            setCycleDuration (Duration.millis (250));
         }

         @Override
         protected void interpolate (double d)
         {
            final double curHeight = EXPAND_HEIGHT * (1.0 - d);
            setPrefHeight (curHeight);
            setTranslateY (-EXPAND_HEIGHT + curHeight);
         }
      };
      this.m_HideInfoBar.onFinishedProperty ().set (new EventHandler<ActionEvent> ()
      {
         @Override
         public void handle (ActionEvent t)
         {
            m_IsShown = false;
            setVisible (false);
         }
      });

      this.m_Timer = new Timer ();
   }

   /**
    * Shows the info bar.
    *
    * @param text The text to display on the info bar.
    * @param showCloseButton True to show the close button, otherwise false.
    * @param iconType The type of icon to display on the information bar.
    * @param hideDelay A delay in seconds to wait until the information bar will
    * automatically hide itself.
    */
   public void show (String text, boolean showCloseButton, int iconType, int hideDelay)
   {
      this.m_IsShown = true;
      this.m_TextLabel.setText (text);
      this.m_CloseButton.setVisible (showCloseButton);
      switch (iconType) {
         case ICON_ERROR:
            this.m_ImageView.setImage (new Image (SdwResources.ICON_CANCEL_32));
            break;
         case ICON_WARNING:
            this.m_ImageView.setImage (new Image (SdwResources.ICON_WARNING));
            break;
         default:
            this.m_ImageView.setImage (new Image (SdwResources.ICON_INFO));

      }
      setVisible (true);
      m_ShowInfoBar.play ();

      if (hideDelay > 0) {
         this.m_Timer.schedule (new TimerTask ()
         {
            @Override
            public void run ()
            {
               cancel ();
               Platform.runLater (new Runnable ()
               {
                  @Override
                  public void run ()
                  {
                     hide ();
                  }
               });
            }
         }, hideDelay * 1000 + 250);
      }
   }

   /**
    * Hides the info bar.
    */
   public void hide ()
   {
      if (this.m_IsShown) {
         this.m_HideInfoBar.play ();
      }
   }

   /**
    * Releases any resources for the information bar.
    */
   public void close ()
   {
      this.m_Timer.cancel ();
   }
}
